//! enhanced_traits.rs 单元测试
//! 
//! 测试重构后的增强trait接口体系，验证：
//! 1. 配置管理trait的正确性
//! 2. 服务生命周期trait的功能
//! 3. 健康检查trait的实现
//! 4. 事件系统trait的工作机制
//! 5. 工厂模式trait的创建逻辑

use redis_rs2::server::enhanced_traits::*;
use redis_rs2::storage::RedisServerMode;
use tokio_test;
use std::sync::Arc;
use std::time::Duration;
use async_trait::async_trait;

// =============================================================================
// Mock实现 - 用于测试trait接口
// =============================================================================

/// Mock配置实现 - 用于测试ServerConfig trait
#[derive(Debug, Clone)]
pub struct MockServerConfig {
    pub mode: RedisServerMode,
    pub bind_address: String,
    pub should_validate: bool,
}

#[async_trait]
impl ServerConfig for MockServerConfig {
    fn mode(&self) -> RedisServerMode {
        self.mode
    }
    
    fn bind_address(&self) -> &str {
        &self.bind_address
    }
    
    fn validate(&self) -> Result<(), String> {
        if self.should_validate {
            Ok(())
        } else {
            Err("Mock validation failed".to_string())
        }
    }
    
    fn extra_config(&self) -> Option<&dyn std::any::Any> {
        None
    }
    
    fn clone_config(&self) -> Box<dyn ServerConfig> {
        Box::new(self.clone())
    }
}

/// Mock服务生命周期实现 - 用于测试ServiceLifecycle trait
#[derive(Debug)]
pub struct MockServiceLifecycle {
    pub name: String,
    pub is_running: std::sync::Arc<std::sync::atomic::AtomicBool>,
    pub start_count: std::sync::Arc<std::sync::atomic::AtomicUsize>,
    pub stop_count: std::sync::Arc<std::sync::atomic::AtomicUsize>,
    pub should_fail_start: bool,
    pub should_fail_stop: bool,
}

impl MockServiceLifecycle {
    pub fn new(name: String) -> Self {
        Self {
            name,
            is_running: Arc::new(std::sync::atomic::AtomicBool::new(false)),
            start_count: Arc::new(std::sync::atomic::AtomicUsize::new(0)),
            stop_count: Arc::new(std::sync::atomic::AtomicUsize::new(0)),
            should_fail_start: false,
            should_fail_stop: false,
        }
    }
    
    pub fn with_start_failure(mut self) -> Self {
        self.should_fail_start = true;
        self
    }
    
    pub fn with_stop_failure(mut self) -> Self {
        self.should_fail_stop = true;
        self
    }
    
    pub fn get_start_count(&self) -> usize {
        self.start_count.load(std::sync::atomic::Ordering::Relaxed)
    }
    
    pub fn get_stop_count(&self) -> usize {
        self.stop_count.load(std::sync::atomic::Ordering::Relaxed)
    }
}

#[async_trait]
impl ServiceLifecycle for MockServiceLifecycle {
    fn service_name(&self) -> &'static str {
        Box::leak(self.name.clone().into_boxed_str())
    }
    
    async fn start(&mut self) -> std::io::Result<()> {
        self.start_count.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
        
        if self.should_fail_start {
            return Err(std::io::Error::new(
                std::io::ErrorKind::Other,
                "Mock start failure"
            ));
        }
        
        self.is_running.store(true, std::sync::atomic::Ordering::Relaxed);
        Ok(())
    }
    
    async fn stop(&mut self) -> std::io::Result<()> {
        self.stop_count.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
        
        if self.should_fail_stop {
            return Err(std::io::Error::new(
                std::io::ErrorKind::Other,
                "Mock stop failure"
            ));
        }
        
        self.is_running.store(false, std::sync::atomic::Ordering::Relaxed);
        Ok(())
    }
    
    fn is_running(&self) -> bool {
        self.is_running.load(std::sync::atomic::Ordering::Relaxed)
    }
    
    async fn graceful_shutdown(&mut self, _timeout_secs: u64) -> std::io::Result<()> {
        self.stop().await
    }
}

/// Mock事件监听器 - 用于测试ServerEventListener trait
#[derive(Debug)]
struct MockEventListener {
    pub name: String,
    pub events_received: std::sync::Arc<std::sync::Mutex<Vec<ServerEvent>>>,
    pub should_fail: bool,
}

impl MockEventListener {
    pub fn new(name: String) -> Self {
        Self {
            name,
            events_received: Arc::new(std::sync::Mutex::new(Vec::new())),
            should_fail: false,
        }
    }
    
    pub fn with_failure(mut self) -> Self {
        self.should_fail = true;
        self
    }
    
    pub fn get_received_events(&self) -> Vec<ServerEvent> {
        self.events_received.lock().unwrap().clone()
    }
    
    pub fn get_event_count(&self) -> usize {
        self.events_received.lock().unwrap().len()
    }
}

#[async_trait]
impl ServerEventListener for MockEventListener {
    async fn on_event(&mut self, event: ServerEvent) -> Result<(), String> {
        if self.should_fail {
            return Err("Mock listener failure".to_string());
        }
        
        self.events_received.lock().unwrap().push(event);
        Ok(())
    }
    
    fn listener_name(&self) -> &str {
        &self.name
    }
}

/// Mock事件发布器 - 用于测试ServerEventPublisher trait
#[derive(Debug)]
pub struct MockEventPublisher {
    pub listeners: std::sync::Arc<std::sync::Mutex<Vec<Arc<dyn ServerEventListener>>>>,
    pub published_events: std::sync::Arc<std::sync::Mutex<Vec<ServerEvent>>>,
    pub should_fail_publish: bool,
    pub should_fail_subscribe: bool,
}

impl MockEventPublisher {
    pub fn new() -> Self {
        Self {
            listeners: Arc::new(std::sync::Mutex::new(Vec::new())),
            published_events: Arc::new(std::sync::Mutex::new(Vec::new())),
            should_fail_publish: false,
            should_fail_subscribe: false,
        }
    }
    
    pub fn with_publish_failure(mut self) -> Self {
        self.should_fail_publish = true;
        self
    }
    
    pub fn with_subscribe_failure(mut self) -> Self {
        self.should_fail_subscribe = true;
        self
    }
    
    pub fn get_published_events(&self) -> Vec<ServerEvent> {
        self.published_events.lock().unwrap().clone()
    }
    
    pub fn get_listener_count(&self) -> usize {
        self.listeners.lock().unwrap().len()
    }
}

#[async_trait]
impl ServerEventPublisher for MockEventPublisher {
    async fn subscribe(&mut self, listener: Arc<dyn ServerEventListener>) -> Result<(), String> {
        if self.should_fail_subscribe {
            return Err("Mock subscribe failure".to_string());
        }
        
        self.listeners.lock().unwrap().push(listener);
        Ok(())
    }
    
    async fn unsubscribe(&mut self, listener_name: &str) -> Result<(), String> {
        let mut listeners = self.listeners.lock().unwrap();
        let original_len = listeners.len();
        listeners.retain(|listener| listener.listener_name() != listener_name);
        
        if listeners.len() == original_len {
            Err(format!("Listener not found: {}", listener_name))
        } else {
            Ok(())
        }
    }
    
    async fn publish(&self, event: ServerEvent) -> Result<(), String> {
        if self.should_fail_publish {
            return Err("Mock publish failure".to_string());
        }
        
        self.published_events.lock().unwrap().push(event);
        Ok(())
    }
}

/// Mock组件工厂 - 用于测试ServiceComponentFactory trait
#[derive(Debug)]
struct MockComponentFactory {
    pub should_fail_redis: bool,
    pub should_fail_cluster: bool,
    pub should_fail_monitoring: bool,
}

impl MockComponentFactory {
    pub fn new() -> Self {
        Self {
            should_fail_redis: false,
            should_fail_cluster: false,
            should_fail_monitoring: false,
        }
    }
    
    pub fn with_redis_failure(mut self) -> Self {
        self.should_fail_redis = true;
        self
    }
    
    pub fn with_cluster_failure(mut self) -> Self {
        self.should_fail_cluster = true;
        self
    }
}

#[async_trait]
impl ServiceComponentFactory for MockComponentFactory {
    async fn create_redis_service(&self, _config: &dyn ServerConfig) -> std::io::Result<Box<dyn ServiceLifecycle>> {
        if self.should_fail_redis {
            return Err(std::io::Error::new(
                std::io::ErrorKind::Other,
                "Mock Redis service creation failed"
            ));
        }
        
        Ok(Box::new(MockServiceLifecycle::new("MockRedisService".to_string())))
    }
    
    async fn create_cluster_service(&self, _config: &dyn ServerConfig) -> std::io::Result<Option<Box<dyn ServiceLifecycle>>> {
        if self.should_fail_cluster {
            return Err(std::io::Error::new(
                std::io::ErrorKind::Other,
                "Mock Cluster service creation failed"
            ));
        }
        
        Ok(Some(Box::new(MockServiceLifecycle::new("MockClusterService".to_string()))))
    }
    
    async fn create_monitoring_service(&self, _config: &dyn ServerConfig) -> std::io::Result<Option<Box<dyn ServiceLifecycle>>> {
        if self.should_fail_monitoring {
            return Err(std::io::Error::new(
                std::io::ErrorKind::Other,
                "Mock Monitoring service creation failed"
            ));
        }
        
        Ok(Some(Box::new(MockServiceLifecycle::new("MockMonitoringService".to_string()))))
    }
    
    fn supported_modes(&self) -> Vec<RedisServerMode> {
        vec![RedisServerMode::Standalone, RedisServerMode::Cluster]
    }
}

// =============================================================================
// 单元测试
// =============================================================================

#[cfg(test)]
mod server_config_tests {
    use super::*;
    
    #[test]
    fn test_mock_server_config_creation() {
        let config = MockServerConfig {
            mode: RedisServerMode::Standalone,
            bind_address: "127.0.0.1:6379".to_string(),
            should_validate: true,
        };
        
        assert_eq!(config.mode(), RedisServerMode::Standalone);
        assert_eq!(config.bind_address(), "127.0.0.1:6379");
        assert!(config.validate().is_ok());
    }
    
    #[test]
    fn test_mock_server_config_validation_failure() {
        let config = MockServerConfig {
            mode: RedisServerMode::Cluster,
            bind_address: "127.0.0.1:7001".to_string(),
            should_validate: false,
        };
        
        assert_eq!(config.mode(), RedisServerMode::Cluster);
        assert!(config.validate().is_err());
    }
    
    #[test]
    fn test_mock_server_config_clone() {
        let config = MockServerConfig {
            mode: RedisServerMode::Standalone,
            bind_address: "127.0.0.1:6379".to_string(),
            should_validate: true,
        };
        
        let cloned = config.clone_config();
        assert_eq!(cloned.mode(), config.mode());
        assert_eq!(cloned.bind_address(), config.bind_address());
    }
    
    #[test]
    fn test_standalone_config_implementation() {
        let config = StandaloneConfig {
            bind_address: "127.0.0.1:6379".to_string(),
        };
        
        assert_eq!(config.mode(), RedisServerMode::Standalone);
        assert_eq!(config.bind_address(), "127.0.0.1:6379");
        assert!(config.validate().is_ok());
        assert!(config.extra_config().is_none());
    }
    
    #[test]
    fn test_standalone_config_validation() {
        let config = StandaloneConfig {
            bind_address: "".to_string(),
        };
        
        assert!(config.validate().is_err());
    }
}

#[cfg(test)]
mod service_lifecycle_tests {
    use super::*;
    
    #[tokio::test]
    async fn test_mock_service_lifecycle_basic() {
        let mut service = MockServiceLifecycle::new("TestService".to_string());
        
        assert_eq!(service.service_name(), "TestService");
        assert!(!service.is_running());
        assert_eq!(service.get_start_count(), 0);
        assert_eq!(service.get_stop_count(), 0);
        
        // 测试启动
        assert!(service.start().await.is_ok());
        assert!(service.is_running());
        assert_eq!(service.get_start_count(), 1);
        
        // 测试停止
        assert!(service.stop().await.is_ok());
        assert!(!service.is_running());
        assert_eq!(service.get_stop_count(), 1);
    }
    
    #[tokio::test]
    async fn test_mock_service_lifecycle_start_failure() {
        let mut service = MockServiceLifecycle::new("FailService".to_string())
            .with_start_failure();
        
        assert!(service.start().await.is_err());
        assert!(!service.is_running());
        assert_eq!(service.get_start_count(), 1);
    }
    
    #[tokio::test]
    async fn test_mock_service_lifecycle_stop_failure() {
        let mut service = MockServiceLifecycle::new("FailService".to_string())
            .with_stop_failure();
        
        // 先启动
        assert!(service.start().await.is_ok());
        assert!(service.is_running());
        
        // 停止失败
        assert!(service.stop().await.is_err());
        // 即使停止失败，运行状态不变（这是mock的行为）
        assert!(service.is_running());
        assert_eq!(service.get_stop_count(), 1);
    }
    
    #[tokio::test]
    async fn test_mock_service_lifecycle_graceful_shutdown() {
        let mut service = MockServiceLifecycle::new("GracefulService".to_string());
        
        assert!(service.start().await.is_ok());
        assert!(service.graceful_shutdown(5).await.is_ok());
        assert!(!service.is_running());
    }
    
    #[tokio::test]
    async fn test_multiple_starts_and_stops() {
        let mut service = MockServiceLifecycle::new("MultiService".to_string());
        
        // 多次启动
        assert!(service.start().await.is_ok());
        assert!(service.start().await.is_ok());
        assert_eq!(service.get_start_count(), 2);
        
        // 多次停止
        assert!(service.stop().await.is_ok());
        assert!(service.stop().await.is_ok());
        assert_eq!(service.get_stop_count(), 2);
    }
}

#[cfg(test)]
mod event_system_tests {
    use super::*;
    
    #[tokio::test]
    async fn test_mock_event_listener_basic() {
        let mut listener = MockEventListener::new("TestListener".to_string());
        
        assert_eq!(listener.listener_name(), "TestListener");
        assert_eq!(listener.get_event_count(), 0);
        
        let event = ServerEvent::Starting {
            mode: RedisServerMode::Standalone,
        };
        
        assert!(listener.on_event(event.clone()).await.is_ok());
        assert_eq!(listener.get_event_count(), 1);
        
        let received_events = listener.get_received_events();
        assert_eq!(received_events.len(), 1);
    }
    
    #[tokio::test]
    async fn test_mock_event_listener_failure() {
        let mut listener = MockEventListener::new("FailListener".to_string())
            .with_failure();
        
        let event = ServerEvent::Error {
            message: "Test error".to_string(),
            recoverable: true,
        };
        
        assert!(listener.on_event(event).await.is_err());
        assert_eq!(listener.get_event_count(), 0);
    }
    
    #[tokio::test]
    async fn test_mock_event_publisher_basic() {
        let mut publisher = MockEventPublisher::new();
        
        assert_eq!(publisher.get_listener_count(), 0);
        assert_eq!(publisher.get_published_events().len(), 0);
        
        // 添加监听器
        let listener = Arc::new(MockEventListener::new("TestListener".to_string()));
        assert!(publisher.subscribe(listener).await.is_ok());
        assert_eq!(publisher.get_listener_count(), 1);
        
        // 发布事件
        let event = ServerEvent::Started {
            mode: RedisServerMode::Standalone,
            bind_addr: "127.0.0.1:6379".to_string(),
        };
        assert!(publisher.publish(event).await.is_ok());
        assert_eq!(publisher.get_published_events().len(), 1);
    }
    
    #[tokio::test]
    async fn test_mock_event_publisher_unsubscribe() {
        let mut publisher = MockEventPublisher::new();
        
        let listener = Arc::new(MockEventListener::new("TestListener".to_string()));
        assert!(publisher.subscribe(listener).await.is_ok());
        assert_eq!(publisher.get_listener_count(), 1);
        
        // 取消订阅
        assert!(publisher.unsubscribe("TestListener").await.is_ok());
        assert_eq!(publisher.get_listener_count(), 0);
        
        // 取消订阅不存在的监听器
        assert!(publisher.unsubscribe("NonExistentListener").await.is_err());
    }
    
    #[tokio::test]
    async fn test_mock_event_publisher_failures() {
        let mut publisher = MockEventPublisher::new()
            .with_subscribe_failure()
            .with_publish_failure();
        
        let listener = Arc::new(MockEventListener::new("TestListener".to_string()));
        assert!(publisher.subscribe(listener).await.is_err());
        
        let event = ServerEvent::Stopping {
            mode: RedisServerMode::Cluster,
        };
        assert!(publisher.publish(event).await.is_err());
    }
}

#[cfg(test)]
mod component_factory_tests {
    use super::*;
    
    #[tokio::test]
    async fn test_mock_component_factory_basic() {
        let factory = MockComponentFactory::new();
        let config = MockServerConfig {
            mode: RedisServerMode::Standalone,
            bind_address: "127.0.0.1:6379".to_string(),
            should_validate: true,
        };
        
        // 测试支持的模式
        let supported_modes = factory.supported_modes();
        assert_eq!(supported_modes.len(), 2);
        assert!(supported_modes.contains(&RedisServerMode::Standalone));
        assert!(supported_modes.contains(&RedisServerMode::Cluster));
        
        // 创建Redis服务
        let redis_service = factory.create_redis_service(&config).await;
        assert!(redis_service.is_ok());
        
        // 创建集群服务
        let cluster_service = factory.create_cluster_service(&config).await;
        assert!(cluster_service.is_ok());
        assert!(cluster_service.unwrap().is_some());
        
        // 创建监控服务
        let monitoring_service = factory.create_monitoring_service(&config).await;
        assert!(monitoring_service.is_ok());
        assert!(monitoring_service.unwrap().is_some());
    }
    
    #[tokio::test]
    async fn test_mock_component_factory_failures() {
        let factory = MockComponentFactory::new()
            .with_redis_failure()
            .with_cluster_failure();
        
        let config = MockServerConfig {
            mode: RedisServerMode::Cluster,
            bind_address: "127.0.0.1:7001".to_string(),
            should_validate: true,
        };
        
        // Redis服务创建失败
        assert!(factory.create_redis_service(&config).await.is_err());
        
        // 集群服务创建失败
        assert!(factory.create_cluster_service(&config).await.is_err());
        
        // 监控服务正常
        assert!(factory.create_monitoring_service(&config).await.is_ok());
    }
}

#[cfg(test)]
mod health_check_tests {
    use super::*;
    
    #[test]
    fn test_health_status_enum() {
        let healthy = HealthStatus::Healthy;
        let degraded = HealthStatus::Degraded("Some issue".to_string());
        let unhealthy = HealthStatus::Unhealthy("Critical issue".to_string());
        
        assert_eq!(healthy, HealthStatus::Healthy);
        assert_ne!(healthy, degraded);
        assert_ne!(degraded, unhealthy);
    }
    
    #[test]
    fn test_diagnostic_info_creation() {
        let info = DiagnosticInfo {
            component: "TestComponent".to_string(),
            status: "Running".to_string(),
            details: Some("All systems operational".to_string()),
        };
        
        assert_eq!(info.component, "TestComponent");
        assert_eq!(info.status, "Running");
        assert!(info.details.is_some());
    }
}

#[cfg(test)]
mod integration_tests {
    use super::*;
    
    #[tokio::test]
    async fn test_trait_composition() {
        // 测试trait组合使用
        let config = MockServerConfig {
            mode: RedisServerMode::Standalone,
            bind_address: "127.0.0.1:6379".to_string(),
            should_validate: true,
        };
        
        let factory = MockComponentFactory::new();
        let mut publisher = MockEventPublisher::new();
        
        // 创建服务
        let mut redis_service = factory.create_redis_service(&config).await.unwrap();
        
        // 添加事件监听器
        let listener = Arc::new(MockEventListener::new("IntegrationListener".to_string()));
        publisher.subscribe(listener).await.unwrap();
        
        // 发布启动事件
        let start_event = ServerEvent::Starting {
            mode: config.mode(),
        };
        publisher.publish(start_event).await.unwrap();
        
        // 启动服务
        redis_service.start().await.unwrap();
        assert!(redis_service.is_running());
        
        // 发布启动完成事件
        let started_event = ServerEvent::Started {
            mode: config.mode(),
            bind_addr: config.bind_address().to_string(),
        };
        publisher.publish(started_event).await.unwrap();
        
        // 验证事件发布
        assert_eq!(publisher.get_published_events().len(), 2);
        
        // 停止服务
        redis_service.stop().await.unwrap();
        assert!(!redis_service.is_running());
    }
    
    #[tokio::test]
    async fn test_error_handling_composition() {
        // 测试错误处理的组合
        let config = MockServerConfig {
            mode: RedisServerMode::Cluster,
            bind_address: "127.0.0.1:7001".to_string(),
            should_validate: false, // 配置验证失败
        };
        
        // 配置验证应该失败
        assert!(config.validate().is_err());
        
        let factory = MockComponentFactory::new().with_redis_failure();
        
        // 服务创建应该失败
        assert!(factory.create_redis_service(&config).await.is_err());
        
        let mut publisher = MockEventPublisher::new().with_publish_failure();
        
        // 事件发布应该失败
        let event = ServerEvent::Error {
            message: "Test error".to_string(),
            recoverable: false,
        };
        assert!(publisher.publish(event).await.is_err());
    }
}